package com.eece496.Server;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.eece496.Database.Classroom;
import com.eece496.Database.Course;
import com.eece496.Database.Enrollment;
import com.eece496.Database.StudentGroups;
import com.eece496.Helpers.CourseInfo;

/**
 * Servlet implementation class ProfRandomGroupAssignmentServlet
 */
public class ProfRandomGroupAssignmentServlet extends MasterServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ProfRandomGroupAssignmentServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Connect();
		String courseNumber = request.getParameter("courseNumber");
		String sectionNumber = request.getParameter("sectionNumber");
		String firstname = request.getParameter("firstname");
		String lastname = request.getParameter("lastname");

		System.out.println(firstname);
		System.out.println(lastname);
		Course CourseDB = new Course();

		int minAmount = Integer.parseInt(request.getParameter("Min"));
		int maxAmount = Integer.parseInt(request.getParameter("Max"));

		// Determine the number of groups required
		System.out.println("Min Group Size: " + minAmount);
		System.out.println("Max Group Size: " + maxAmount);

		// checking the difference.  If it is greater than 1, redirect to groups page
		int difference = maxAmount - minAmount;
		if (difference > 1) {
			request.setAttribute("courseNumber", courseNumber);
			request.setAttribute("sectionNumber", sectionNumber);
			request.setAttribute("firstname", firstname);
			request.setAttribute("lastname", lastname);

			request.getRequestDispatcher("/Professor/Professor-add-group.jsp")
					.forward(request, response);
		} else {
			String CPEN = "CPEN";
			String ELEC = "ELEC";
			Enrollment EnrollmentDB = new Enrollment();
			EnrollmentDB.Setup(connection);
			ArrayList<Integer> CPENList = new ArrayList<Integer>();
			ArrayList<Integer> ELECList = new ArrayList<Integer>();

			ArrayList<Integer> ExtraList = new ArrayList<Integer>();

			try {
				CPENList = EnrollmentDB.GetStudentGPA(courseNumber,
						sectionNumber, CPEN);
				ELECList = EnrollmentDB.GetStudentGPA(courseNumber,
						sectionNumber, ELEC);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// get class size
			int size = CPENList.size() + ELECList.size();
			System.out.println("The Size is: " + size);
			// int size = 172;
			int maxgroup = size / maxAmount;
			int mingroup = 0;
			int remainder = size % maxAmount;
			System.out.println("Remainder is: " + remainder);
			if (remainder == 0) {
				mingroup = 0;
			}

			else {
				// find the remainder by dividing size by minamount
				int minReminder = size % minAmount;
				if (minReminder == 0) {
					mingroup = size / minAmount;
					maxgroup = 0;
				} else {
					mingroup = (size - ((maxgroup - (minAmount - remainder)) * maxAmount))
							/ minAmount;
					maxgroup = maxgroup - (minAmount - remainder);
				}
			}
			System.out.println("Number of minGroups: " + mingroup);
			System.out.println("Number of maxGroups: " + maxgroup);

			int numOfGroups = maxgroup + mingroup;

			// Get the Classroom list
			Classroom classroomDB = new Classroom();
			classroomDB.Setup(connection);
			ArrayList<String> classroomList = new ArrayList<String>();
			try {
				classroomList = classroomDB.GetListOfClassrooms();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			// For keeping track of classrooms
			int classCount = 0;

			// Divide group into two
			String div = "AB";
			int divCount = 0;
			// Get the Student List
			// group tracker
			int groupTracker = 1;

			// Starting with the CPEN students
			int GroupNumber = 1;
			for (int i = 0; i < maxgroup; i++) {
				// //////////TOP////////////////////////////
				if (groupTracker >= 4) {
					GroupNumber = 2;
				}
				int amount = 0;
				if (CPENList.size() == 0)
					break;

				// For Testing
				int count1 = 0;
				int count2 = 0;

				// Selecting top students to be placed in Groups
				for (int count = 0; count < CPENList.size(); count++) { // System.out.println("Added "
					// + students);

					System.out.println("ClassRoom Count: " + classCount);
					if (classCount > (numOfGroups / 2)) {
						divCount = 1;
					}

					if (classCount > (numOfGroups / 2) || amount == numOfGroups) {
						classCount = 0;
						GroupNumber = 1;
						if ((groupTracker >= 4)) {
							GroupNumber = 2;
						}

					}

					String gNum = Integer.toString(GroupNumber);

					StudentGroups firstStudent = new StudentGroups(gNum,
							div.substring(divCount, divCount + 1),
							CPENList.get(count), courseNumber, sectionNumber,
							classroomList.get(classCount), 1);
					firstStudent.Setup(connection);
					try {
						firstStudent.Insert();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					GroupNumber = GroupNumber + 2;

					amount++;
					count1++;

					if (amount == CPENList.size()) {
						System.out.println("Number of students remaining: "
								+ CPENList.size());
						// for (int j = 0; j < CPENList.size()+1; j++) {
						// System.out.println("Removed " + CPENList.get(0));
						CPENList.removeAll(CPENList);
						// }
						System.out.println("Number of students remaining: "
								+ CPENList.size());
						break;
					}

					if (amount == numOfGroups) {
						divCount = 0;
						GroupNumber = 1;
						classCount = 0;
						for (int j = 0; j < numOfGroups; j++) {
							System.out.println("Removed " + CPENList.get(0));
							CPENList.remove(0);

						}
						break;
					}

					// increment classroom list
					classCount++;
				}

				groupTracker++;
				// ////////////////BOTTOM/////////////////////////////
				GroupNumber = 1;
				amount = 0;

				if (groupTracker >= 4) {
					GroupNumber = 2;
				}

				if (CPENList.size() == 0)
					break;

				// System.out.println(CPENList.size());

				// Selecting bottom students to be placed in Groups
				for (int back = (CPENList.size() - 1); back > (CPENList.size() - (maxgroup
						+ mingroup + 1)); back--) {
					System.out.println("ClassRoom Count: " + classCount);
					if (classCount > (numOfGroups / 2)) {
						divCount = 1;
					}

					if (classCount > (numOfGroups / 2) || amount == numOfGroups) {
						classCount = 0;
						GroupNumber = 1;
						if ((groupTracker >= 4)) {
							GroupNumber = 2;
						}

					}
					// System.out.println("Added " + CPENList.get(back));

					String gNum = Integer.toString(GroupNumber);
					StudentGroups firstStudent = new StudentGroups(gNum,
							div.substring(divCount, divCount + 1),
							CPENList.get(back), courseNumber, sectionNumber,
							classroomList.get(classCount), 1);
					firstStudent.Setup(connection);
					try {
						firstStudent.Insert();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					GroupNumber = GroupNumber + 2;
					amount++;
					count1++;
					if (amount == CPENList.size()) {
						System.out.println("Number of students remaining: "
								+ CPENList.size());
						// for (int j = 0; j < CPENList.size()+1; j++) {
						// System.out.println("Removed " + CPENList.get(0));
						CPENList.removeAll(CPENList);
						// }
						System.out.println("Number of students remaining: "
								+ CPENList.size());
						break;
					}

					if (amount == numOfGroups) {
						divCount = 0;
						GroupNumber = 1;
						classCount = 0;
						for (int j = 0; j < numOfGroups; j++) {
							System.out.println("Removed "
									+ CPENList.get((CPENList.size() - 1)));
							CPENList.remove((CPENList.size() - 1));
						}

						break;
					}
					// increment classroom list
					classCount++;
				}

				groupTracker++;
			}

			// Reset all Values
			// //////////ELEC Students Now///////////////////

			// For keeping track of classrooms
			classCount = 0;

			// Divide group into two
			divCount = 0;

			// Get the Student List group tracker
			groupTracker = 1;
			GroupNumber = 1;

			for (int i = 0; i < maxgroup; i++) {

				// //////////TOP////////////////////////////
				if (groupTracker >= 4) {
					GroupNumber = 2;
				}
				int amount = 0;
				if (ELECList.size() == 0)
					break;

				// For Testing
				int count1 = 0;
				int count2 = 0;

				// Selecting top students to be placed in Groups
				for (int count = 0; count < ELECList.size(); count++) { // System.out.println("Added "
					// + students);

					System.out.println("ClassRoom Count: " + classCount);
					if (classCount > (numOfGroups / 2)) {
						divCount = 1;
					}

					if (classCount > (numOfGroups / 2) || amount == numOfGroups) {
						classCount = 0;
						GroupNumber = 1;
						if ((groupTracker >= 4)) {
							GroupNumber = 2;
						}
					}

					String gNum = Integer.toString(GroupNumber);

					StudentGroups firstStudent = new StudentGroups(gNum,
							div.substring(divCount, divCount + 1),
							ELECList.get(count), courseNumber, sectionNumber,
							classroomList.get(classCount), 1);
					firstStudent.Setup(connection);
					try {
						int groupsize = 0;
						groupsize = firstStudent.GetGroupSize(gNum,
								div.substring(divCount, divCount + 1),
								courseNumber, sectionNumber);
						System.out.println(groupsize);
						if (groupsize < (maxAmount / 2)) {
							firstStudent.Insert();
						} else {
							ExtraList.add(ELECList.get(count));
						}
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					GroupNumber = GroupNumber + 2;

					amount++;
					count1++;

					if (amount == ELECList.size()) {
						System.out.println("Number of students remaining: "
								+ ELECList.size());
						// for (int j = 0; j < CPENList.size()+1; j++) {
						// System.out.println("Removed " + CPENList.get(0));
						ELECList.removeAll(ELECList);
						// }
						System.out.println("Number of students remaining: "
								+ ELECList.size());
						break;
					}

					if (amount == numOfGroups) {
						divCount = 0;
						GroupNumber = 1;
						classCount = 0;
						for (int j = 0; j < numOfGroups; j++) {
							System.out.println("Removed " + ELECList.get(0));
							ELECList.remove(0);

						}
						break;
					}

					// increment classroom list
					classCount++;
				}

				groupTracker++;
				// ////////////////BOTTOM/////////////////////////////
				GroupNumber = 1;
				amount = 0;

				if (groupTracker >= 4) {
					GroupNumber = 2;
				}

				if (ELECList.size() == 0)
					break;

				// System.out.println(CPENList.size());

				// Selecting bottom students to be placed in Groups
				for (int back = (ELECList.size() - 1); back > (ELECList.size() - (maxgroup
						+ mingroup + 1)); back--) {
					System.out.println("ClassRoom Count: " + classCount);
					if (classCount > (numOfGroups / 2)) {
						divCount = 1;
					}

					if (classCount > (numOfGroups / 2) || amount == numOfGroups) {
						classCount = 0;
						GroupNumber = 1;
						if ((groupTracker >= 4)) {
							GroupNumber = 2;
						}

					}
					// System.out.println("Added " + CPENList.get(back));

					String gNum = Integer.toString(GroupNumber);
					StudentGroups firstStudent = new StudentGroups(gNum,
							div.substring(divCount, divCount + 1),
							ELECList.get(back), courseNumber, sectionNumber,
							classroomList.get(classCount), 1);
					firstStudent.Setup(connection);
					try {
						int groupsize = 0;
						groupsize = firstStudent.GetGroupSize(gNum,
								div.substring(divCount, divCount + 1),
								courseNumber, sectionNumber);
						System.out.println(groupsize);
						if (groupsize < (maxAmount / 2)) {
							firstStudent.Insert();
						} else {
							ExtraList.add(ELECList.get(back));
						}
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					GroupNumber = GroupNumber + 2;
					amount++;
					count1++;
					if (amount == ELECList.size()) {
						System.out.println("Number of students remaining: "
								+ ELECList.size());
						// for (int j = 0; j < CPENList.size()+1; j++) {
						// System.out.println("Removed " + CPENList.get(0));
						ELECList.removeAll(ELECList);
						// }
						System.out.println("Number of students remaining: "
								+ ELECList.size());
						break;
					}

					if (amount == numOfGroups) {
						divCount = 0;
						GroupNumber = 1;
						classCount = 0;
						for (int j = 0; j < numOfGroups; j++) {
							System.out.println("Removed "
									+ ELECList.get((ELECList.size() - 1)));
							ELECList.remove((ELECList.size() - 1));
						}

						break;
					}
					// increment classroom list
					classCount++;
				}

				groupTracker++;
			}

			System.out.println(ExtraList.get(0));
			System.out.println(ExtraList.get(1));
			int theGroupSize = 0;
			int classroomCount = 0;
			int gNum = 1;
			// Go through the list starting with A
			for (Integer intr : ExtraList) {
				String str = "A";
				for (int i = 0; i < ((mingroup + maxgroup) * 2); i++) {

					if (i > (maxgroup * 2) + 1) {
						str = "B";
						classroomCount = 0;
						gNum = 1;
					}

					if (gNum == (maxgroup * 2) + 1) {
						gNum = 1;
						classroomCount = 0;
					}

					String str1 = Integer.toString(gNum);
					StudentGroups students = new StudentGroups();
					students.Setup(connection);
					try {
						theGroupSize = students.GetGroupSize(str1, str,
								courseNumber, sectionNumber);
						System.out.println("Division " + str + " Group " + gNum
								+ " Size: " + theGroupSize);
					} catch (SQLException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					// System.out.println(theGroupSize);
					if (theGroupSize < ((maxgroup + mingroup) / 2)) {
						StudentGroups firstStudent = new StudentGroups(str1,
								str, intr, courseNumber, sectionNumber,
								classroomList.get(classroomCount), 1);
						firstStudent.Setup(connection);
						try {
							firstStudent.Insert();
							break;
						} catch (SQLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

					if (i != 0 && i % 2 == 0) {
						classroomCount++;
					}
					gNum++;
				}
			}

			request.setAttribute("courseNumber", courseNumber);
			request.setAttribute("sectionNumber", sectionNumber);
			request.setAttribute("firstname", firstname);
			request.setAttribute("lastname", lastname);
			request.getRequestDispatcher(
					"/Professor/Professor-Course-Portal.jsp").forward(request,
					response);
		}
	}
}
